﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "GcmpCollaborationInterface.h"
#include "GbmpQuickCast.h"

namespace gcmp
{
    /// \brief 当前在此机器上登录的用户从服务器端获取的唯一编号提供者
    class GCMP_COLLABORATION_INTERFACE_EXPORT IIdOfUserLoginToMachineProvider
    {
        DEFINE_CAST_BASE(gcmp::IIdOfUserLoginToMachineProvider)
    public:
        /// \brief 获取当前在此机器上登录的用户从服务器端获取的唯一编号
        /// \return uint16_t
        virtual uint16_t GetIdOfUserLoginToMachine() const = 0;

        /// \brief 设置当前在此机器上登录的用户从服务器端获取的唯一编号
        /// \param IdOfUserLoginToMachine此机器上登录的用户从服务器端获取的唯一编号
        /// \return void
        virtual void SetIdOfUserLoginToMachine(uint16_t idOfUserLoginToMachine) = 0;

        /// \brief 析构函数
        virtual ~IIdOfUserLoginToMachineProvider() = 0;
    };
    
    /// \brief 工作单元打开计数器
    class GCMP_COLLABORATION_INTERFACE_EXPORT IDatasetOpenCounter
    {
        DEFINE_CAST_BASE(gcmp::IDatasetOpenCounter)
    public:
        /// \brief 获取当前在此机器上的工作单打开计数
        /// \param projectId 项目Id
        /// \param idOfUserLoginToMachine 当前在此机器上登录的用户从服务器端获取的唯一编号
        /// \return uint16_t
        virtual uint16_t GetCount(const std::wstring & projectId, uint16_t idOfUserLoginToMachine) const = 0;

        /// \brief 增加计数
        /// \param projectId 项目Id
        /// \return void
        virtual void IncreaseCount(const std::wstring & projectId) = 0;

        /// \brief 析构函数
        virtual ~IDatasetOpenCounter() = 0;
    };

    /// \brief 构件级协同ElementId前缀产生器
    class GCMP_COLLABORATION_INTERFACE_EXPORT ElementIdPrefixGenerater final
    {
    public:
        /// \brief 获取实例
        static ElementIdPrefixGenerater * Get();

        /// \brief 注册当前在此机器上登录的用户从服务器端获取的唯一编号提供者
        /// \param provider 新提供者
        /// \return 返回旧的提供者
        IIdOfUserLoginToMachineProvider * RegisterIdOfUserLoginToMachineProvider(IIdOfUserLoginToMachineProvider * provider);

        /// \brief 注册工作单元打开计数器
        /// \param provider 新提供者
        /// \return 返回旧的提供者
        IDatasetOpenCounter * RegisterDatasetOpenCountProvider(IDatasetOpenCounter * provider);

        /// \brief 获取项目内唯一的ElementId前缀
        /// \param pErrorMessage 错误消息，发生错误并且非空时传出
        /// \return 可以用于ElementId的前缀，项目内唯一
        uint32_t GetElementIdPrefix(std::wstring * pErrorMessage) const;

        /// \brief 设置工作单元打开计数器
        /// \return void
        void IncreaseCount();

        /// \brief 设置此机器上登录的用户从服务器端获取的唯一编号提供者
        /// \param IdOfUserLoginToMachine 此机器上登录的用户从服务器端获取的唯一编号提供者
        /// \return void
        void SetIdOfUserLoginToMachine(uint16_t IdOfUserLoginToMachine);

        /// \brief 设置项目Id
        /// \param projectId 项目Id
        /// \return void
        void SetProjectId(const std::wstring& projectId);

        /// \brief 获取项目Id
        /// \return std::wstring 项目Id
        const std::wstring& GetProjectId() const;

        ~ElementIdPrefixGenerater();
    private:
        IIdOfUserLoginToMachineProvider * m_IdOfUserLoginToMachineProvider = nullptr;
        IDatasetOpenCounter * m_DatasetOpenCounter = nullptr;
        std::wstring m_projectId;
    };
}
